import java.io.File;
import java.io.IOException;
import java.util.Iterator;

import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.*;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

class NamespaceContextProvider implements NamespaceContext {
    String boundPrefix, boundURI;

    NamespaceContextProvider(String prefix, String URI) {
        boundPrefix = prefix;
        boundURI = URI;
    }

    public String getNamespaceURI(String prefix) {
        if(prefix.equals(boundPrefix)) {
            return boundURI;
        } else if(prefix.equals(XMLConstants.XML_NS_PREFIX)) {
            return XMLConstants.XML_NS_URI;
        } else if(prefix.equals(XMLConstants.XMLNS_ATTRIBUTE)) {
            return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
        } else {
            return XMLConstants.NULL_NS_URI;
        }
    }

    public String getPrefix(String namespaceURI) {
        if(namespaceURI.equals(boundURI)) {
            return boundPrefix;
        } else if(namespaceURI.equals(XMLConstants.XML_NS_URI)) {
            return XMLConstants.XML_NS_PREFIX;
        } else if(namespaceURI.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI)) {
            return XMLConstants.XMLNS_ATTRIBUTE;
        } else {
            return null;
        }
    }

    public Iterator<String> getPrefixes(String namespaceURI) {
        // not implemented for the example
        return null;
    }
}

public class Configuration {
	String fileToRead = "";
	String rootTag = "";
	String identifier = "";
	String pointer = "";
	
	public Configuration() {
		this.fileToRead = 
		this.rootTag = 
		this.identifier = 
		this.pointer = "";
	}
	
	public Configuration(String file, String root, String ident, String pnt) {
		this.fileToRead = file;
		this.rootTag = root;
		this.identifier = ident;
		this.pointer = pnt;
	}
	
	public String getNodeViaPath(String path) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
		DocumentBuilderFactory dom = DocumentBuilderFactory.newInstance();
		dom.setNamespaceAware(true);
		DocumentBuilder builder = dom.newDocumentBuilder();
		Document doc = builder.parse(new File(this.fileToRead));
		
		XPathFactory factory = XPathFactory.newInstance();
		XPath xpath = factory.newXPath();
		XPathExpression expr = xpath.compile(path);
		
		return expr.evaluate(doc);
	}
	
	public String getNodeViaPath(String path, String prefix, String nameSpaceURI) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
		DocumentBuilderFactory dom = DocumentBuilderFactory.newInstance();
		dom.setNamespaceAware(true);
		DocumentBuilder builder = dom.newDocumentBuilder();
		Document doc = builder.parse(new File(this.fileToRead));
		
		XPathFactory factory = XPathFactory.newInstance();
		XPath xpath = factory.newXPath();
		
		xpath.setNamespaceContext(new NamespaceContextProvider(prefix, nameSpaceURI));		
		XPathExpression expr = xpath.compile(path);
		
		return expr.evaluate(doc);
	}
	
	public String[] getNodeListViaPath(String path) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
		DocumentBuilderFactory dom = DocumentBuilderFactory.newInstance();
		dom.setNamespaceAware(true);
		DocumentBuilder builder = dom.newDocumentBuilder();
		Document doc = builder.parse(new File(this.fileToRead));
		
		XPathFactory factory = XPathFactory.newInstance();
		XPath xpath = factory.newXPath();
		XPathExpression expr = xpath.compile(path);
		NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
		String[] results = new String[nodes.getLength()];
		for (int i = 0; i < nodes.getLength(); i++)
			results[i] = nodes.item(i).getNodeValue();
		return results;
	}
	
	public String[] readFromConfig(String stops[]) throws ParserConfigurationException, SAXException, IOException {		
		if ((stops == null) || (stops.length == 0))
			return null;
		String results[] = new String[stops.length];
		DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
		Document doc = docBuilder.parse(new File(this.fileToRead));
		doc.getDocumentElement().normalize();
		NodeList nodes = doc.getElementsByTagName(this.rootTag);
		for (int i = 0; i < nodes.getLength(); i++) {
			Node node = nodes.item(i);				
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				Element element = (Element) node;
				NodeList id	  = element.getElementsByTagName(this.identifier);					
				if (((((Node) id.item(0)).getChildNodes()).item(0).getNodeValue().trim()).equalsIgnoreCase(this.pointer)) {
					for (int j = 0; j < stops.length; j++) {
						id = element.getElementsByTagName(stops[j]);
						results[j] = (((Node) id.item(0)).getChildNodes()).item(0).getNodeValue().trim();
					}
				}
			}
		}
		return results;
	}
}
